#!/usr/bin/env python

"""
Mind 2 Music
Copyright (C) 2010  Sytze K. Zeijlmaker

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""

try:
	from sndobj import *
	Sound=True
except:
	print "SndObj could not be loaded"
	Sound=False
import time
from threading import Thread

class Composition:
	def __init__(self):
		self.temperament=12
		self.beat=4
		self.bmp=100

class Notes:
	def __init__(self):
		self.l=[]
	
	def Add(self,time,pitch,length):
		self.l.append((time,pitch,length))
	
	def Get(self,x,y):
		for n in self.l:
			if n[1]==y and n[0]<=x and n[0]+n[2]>x:
				return n
		return None
	
	def Change(self,n1,n2):
		self.l.remove(n1)
		self.l.append(n2)
	
	def getLength(self):
		r=0
		for n in self.l:
			if n[0]+n[2]>r:
				r=n[0]+n[2]
		return r
	
	def Play(self):
		thread=Player(self,0)
		thread.start()

class Player(Thread):
	def __init__(self,notes,pos,edit=None):
		Thread.__init__(self)
		self.n=notes
		self.pos=pos
		self.abort=False
		self.edit=edit
	
	def run(self):
		if Sound==False:
			print "Unable to play sound"
			self.abort=True
			return
		
		t=SndRTThread()
		harm=HarmTable(1024,4,SAW) # SINE, SAW, SQUARE or BUZZ. 
		note=[]
		
		for n in self.n.l:
			osc=Oscili(harm,2.0**((n[1]+12)/12.0)*110.0,0)
			t.AddOutput(1,osc)
			note.append((n,osc))
		
		t.ProcOn()
		
		print "start"
		for i in range(self.pos,self.n.getLength()+1):
			time.sleep(0.1)
			self.pos=i
			if self.edit!=None:
				self.edit.queue_draw_area(0,0,self.edit.allocation.width,self.edit.allocation.height)
			
			for n in note:
				if n[0][0]==i:
					n[1].SetAmp(5000)
				if n[0][0]+n[0][2]==i:
					n[1].SetAmp(0)
					#t.DeleteOutput(1,n[1])
					
			if self.abort==True:
				break
		
		print "stop"
		t.ProcOff()
		self.abort=True
		time.sleep(1)
		#time.sleep(10000)
		return

n=Notes()
"""
n.Add(0,24,36)

n.Add(0,12,3)
n.Add(0,15,3)
n.Add(0,19,3)

n.Add(4,12,3)
n.Add(4,17,3)
n.Add(4,8,3)

n.Add(8,7,3)
n.Add(8,11,3)
n.Add(8,14,3)
n.Add(8,17,3)

n.Add(12,12,3)
n.Add(12,3,3)
n.Add(12,7,3)

n.Add(16,12,3)
n.Add(16,5,3)
n.Add(16,8,3)

n.Add(20,6,3)
n.Add(20,9,3)
n.Add(20,12,3)
n.Add(20,15,3)

n.Add(24,7,3)
n.Add(24,11,3)
n.Add(24,14,3)
n.Add(24,17,3)

n.Add(28,8,3)
n.Add(28,11,3)
n.Add(28,14,3)
n.Add(28,17,3)

n.Add(32,0,4)
n.Add(32,11,4)
n.Add(32,16,4)
n.Add(32,19,4)
"""

if __name__=="__main__":
	n.Play()

